package com.hzw.code.vm

import android.annotation.SuppressLint
import android.content.pm.ActivityInfo
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.blankj.utilcode.util.RomUtils
import com.hzw.code.R
import com.hzw.code.annotation.BindViewModel
import com.hzw.code.pageState.OnRetryListener
import com.hzw.code.pageState.OnShowHideViewListener
import com.hzw.code.pageState.PageStateManager
import com.hzw.code.pageState.State
import com.hzw.code.utils.StatusBarUtils
import com.hzw.code.vm.event.Event
import com.scwang.smartrefresh.layout.listener.OnRefreshListener
import kotlinx.android.synthetic.main.page_layout.*

/**
 *
 * @Author:         HuaZhongWei
 * @CreateDate:     2020/4/20 10:47
 *
 * @Description:    带ViewModel的Activity，有网络请求的都建议用这个
 *
 */
abstract class PageActivity : AppCompatActivity(), IView {

    var pageStateManager: PageStateManager? = null

    open val isNeedPageStateManager: Boolean = true

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        setContentView(R.layout.page_layout)
        changeStatusBarColor()
        initTitle()
        if (isNeedPageStateManager) {
            initContent()
        } else {
            contentContainer.addView(View.inflate(this, getLayoutResId(), null))
        }
        initViewModel()
        init(savedInstanceState)
    }

    abstract fun init(savedInstanceState: Bundle?)

    private fun initViewModel() {
        javaClass.declaredFields
            .filter { field ->
                field.isAnnotationPresent(BindViewModel::class.java)
            }
            .forEach { field ->
                val viewModel: AbsViewModel = ViewModelProvider(this).get(field.getAnnotation(BindViewModel::class.java)!!.model.java)
                initCommonEvent(viewModel)
                field.set(this, viewModel)
            }
    }

    /**
     * 改变状态栏颜色
     */
    private fun changeStatusBarColor() {
        if (isNeedTranslucentStatus()) {
            StatusBarUtils.setStatusBarTranslucent(this)
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT < Build.VERSION_CODES.M && RomUtils.isVivo()) { //5.0及以上
                StatusBarUtils.setStatusBarColor(this, getStatusBarColorForLollipop())
            } else {
                StatusBarUtils.setStatusBarColor(this, getStatusBarColor())
            }
            StatusBarUtils.setStatusBarFontAndIconColor(this, true)
        }
    }

    /**
     * 状态栏颜色，但是这里不包括Android 5.0的版本
     */
    open fun getStatusBarColor(): Int {
        return Color.WHITE
    }

    /**
     * 状态栏颜色，只针对Android 5.0的版本
     * 如vivo 5.0的系统状态栏字体颜色只能是白色，所以状态栏不能为白色，否则看不见
     */
    open fun getStatusBarColorForLollipop(): Int {
        return Color.parseColor("#33000000")
    }

    /**
     * 是否需要状态栏透明, 默认为false
     * 设置透明时，需要在适当的位置加上 android:fitsSystemWindows="true"
     */
    open fun isNeedTranslucentStatus(): Boolean {
        return false
    }

    private fun initCommonEvent(viewModel: AbsViewModel) {
        viewModel.eventLiveData.observe(this, Observer { commonEvent ->
            when (commonEvent.event) {
                Event.SHOW_LOADING -> showLoading()
                Event.HIDE_LOADING -> hideLoading()
                Event.CONTENT -> showContent()
                Event.ERROR -> showError()
                Event.NET_ERROR -> showNetError()
                Event.EMPTY -> showEmpty()
                Event.TOAST -> showToast(commonEvent.msg)
            }
        })
    }

    private fun initTitle() {
        val titleView = initTitleLayout()
        if (titleView != null) {
            titleContainer.visibility = View.VISIBLE
            titleContainer.addView(titleView.rootLayout)
        } else {
            titleContainer.visibility = View.GONE
        }
    }

    private fun initContent() {
        pageStateManager = initPageStateManager() ?: PageStateManager.Builder(this)
            .loadingLayoutResId()
            .contentLayoutResId(getLayoutResId())
            .errorView(
                onRefreshListener = OnRefreshListener { onRefreshForError(it) },
                onRetryListener = object : OnRetryListener {
                    override fun onRetry() {
                        onRetryForError()
                    }
                }
            )
            .emptyView(
                onRefreshListener = OnRefreshListener {
                    onRefreshForEmpty(it)
                },
                onRetryListener = object : OnRetryListener {
                    override fun onRetry() {
                        onRetryForEmpty()
                    }
                }
            )
            .netErrorView(
                onRefreshListener = OnRefreshListener { onRefreshForNetError(it) },
                onRetryListener = object : OnRetryListener {
                    override fun onRetry() {
                        onRetryForNetError()
                    }
                }
            )
            .onShowHideViewListener(object : OnShowHideViewListener {
                override fun onShowView(view: View, state: State) {
                    onShowViewForPage(view, state)
                }

                override fun onHideView(view: View, state: State) {
                    onHideViewForPage(view, state)
                }
            })
            .build()
        contentContainer.addView(pageStateManager?.rootLayout)
    }

    override fun showLoading() {
        pageStateManager?.showLoading()
    }

    override fun hideLoading() {
        pageStateManager?.hideLoading()
    }

    override fun showContent() {
        pageStateManager?.showContentView()
    }

    override fun showError() {
        pageStateManager?.showErrorView()
    }

    override fun showNetError() {
        pageStateManager?.showNetErrorView()
    }

    override fun showEmpty() {
        pageStateManager?.showEmptyView()
    }

    abstract fun getLayoutResId(): Int

    open fun initPageStateManager(): PageStateManager? {
        return null
    }

    open fun initTitleLayout(): TitleLayout? {
        return null
    }
}